﻿using System;

namespace ArgusLib.Fractals
{
	public interface IFractal
	{
		/// <summary>
		/// Gets a DataSet which represents the results of a previous calculation.
		/// </summary>
		IDataSet DataSet { get; }

		/// <summary>
		/// Gets or sets a <see cref="IDataSetConstructor"/> which will be used to
		/// initialize the <see cref="IFractal.DataSet"/> field whenever <see cref="IFractal.StartCalculation"/>
		/// or <see cref="IFractal.Calculate"/> is called.
		/// </summary>
		IDataSetProvider DataSetProvider { get; set; }

		/// <summary>
		/// Gets or sets the parameters which specify how the fractal is calculated.
		/// </summary>
		IParameter Parameter { get; set; }

		/// <summary>
		/// Gets a value indicating whether a calculation is currently running.
		/// </summary>
		bool IsCalculating { get; }

		/// <summary>
		/// Starts an asynchronious calculation. Should throw an Exception if there already is a calculation running.
		/// </summary>
		void StartCalculation();

		/// <summary>
		/// Starts a synchronious calculation.
		/// </summary>
		void Calculate();

		/// <summary>
		/// Aborts an asynchronious calculation.
		/// </summary>
		void AbortCalculation(bool join);

		/// <summary>
		/// Occurs when the progress of a currently running calculation changes.
		/// </summary>
		event CalculationProgressChangedEventHandler CalculationProgressChanged;

		/// <summary>
		/// Occurs when a calculation was aborted.
		/// </summary>
		event CalculationAbortedEventHandler CalculationAborted;

		/// <summary>
		/// Occurs when a calculation was finished.
		/// </summary>
		event CalculationFinishedEventHandler CalculationFinished;
	}
}
